package com.tensquare.user.controller;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.tensquare.entity.Result;
import com.tensquare.entity.StatusCode;
import com.tensquare.user.exception.UserInvalidException;
import com.tensquare.user.service.TbUserService;
import com.tensquare.user.service.AuthService;
import com.tensquare.util.IdWorker;
import com.tensquare.util.RedisConstant;
import com.tensquare.util.StringHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户授权控制器
 */
@Slf4j
@RestController
@RequestMapping(value = "auth")
public class AuthController {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private TbUserService tbUserService;
    @Autowired
    private AuthService authService;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @RequestMapping(value = "/captcha")
    public Result getCaptcha() throws IOException {
        String capText = defaultKaptcha.createText();
        String redisCapText = capText.toLowerCase();
        BufferedImage capImg = defaultKaptcha.createImage(capText);
        //用于区别是哪个不同用户的验证码
        long uuid = idWorker.nextId();
        redisTemplate.opsForValue().set(RedisConstant.REDIS_LOGIN_CAPTCHA_KEY + ":" + uuid, redisCapText, RedisConstant.REDIS_LOGIN_CAPTCHA_EXPIRED_TIME, TimeUnit.SECONDS);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(capImg, "jpg", outputStream);
        Base64.Encoder encoder = Base64.getEncoder();
        HashMap<String, Object> map = new HashMap<>();
        map.put("captcha", encoder.encodeToString(outputStream.toByteArray()));
        map.put("capKey", String.valueOf(uuid));
        return new Result(true, "获取成功", StatusCode.OK, map);
    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result login(@RequestBody Map<String, String> map) throws UserInvalidException {
        String code = map.get("code");
        String captchaKey = map.get("captchaKey");
        Result x = checkCaptcha(code, captchaKey);
        if (x != null) return x;
        Map<String, Object> login = tbUserService.login(map);
        return new Result(true, "登录成功", StatusCode.OK, login);
    }

    @RequestMapping(value = "/isLogin", method = RequestMethod.GET)
    public Result isLogin(HttpServletRequest request) {
        String userId = request.getHeader("userId");
        String userName = tbUserService.isLogin(userId);
        if (null != userName) {
            return new Result(true, "已经登录", StatusCode.OK,userName);
        }else {
            return new Result(false, "未登录", StatusCode.OK);
        }
    }

    /**
     * 刷新Token
     *
     */
    @RequestMapping(value = "/token/refresh", method = RequestMethod.GET)
    public Result refresh(HttpServletRequest request) throws Exception {
        String userId = request.getHeader("userId");
        if (StringHelper.isEmpty(userId)) {
            return new Result(false, "userId不能为空", StatusCode.PARAMS_IN_ERROR);
        }
        return new Result(true, "刷新成功", StatusCode.OK, authService.refresh(userId));
    }

    /**
     * 判断验证码是否过期
     *
     * @param code       验证码
     * @param captchaKey 验证码对应redis的键
     */
    private Result checkCaptcha(String code, String captchaKey) {
        if (StringHelper.isEmpty(captchaKey)) {
            return new Result(false, "captcha key is null", StatusCode.PARAMS_IN_ERROR);
        }
        String captchaValue = redisTemplate.opsForValue().get(RedisConstant.REDIS_LOGIN_CAPTCHA_KEY + ":" + captchaKey);
        if (null == code) {
            return new Result(false, "验证码为空", StatusCode.CAPTCHA_IS_NULL);
        }
        if (!code.equals(captchaValue)) {
            return new Result(false, "验证码错误", StatusCode.CAPTCHA_EXPIRED);
        }
        return null;
    }

}
